package com.all.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class StretchScrollView extends ScrollView {
	 private static final int MSG_REST_POSITION = 0x01;

	    /** The max scroll height. */
	    private static final int MAX_SCROLL_HEIGHT = 400;
	    /** Damping, the smaller the greater the resistance */
	    private static final float SCROLL_RATIO = 0.4f;

	    private View mChildRootView;

	    private float mTouchY;
	    private boolean mTouchStop = false;

	    private int mScrollY = 0;
	    private int mScrollDy = 0;

	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			if (MSG_REST_POSITION == msg.what) {
				if (mScrollY != 0 && mTouchStop) {
					mScrollY -= mScrollDy;
					if ((mScrollDy < 0 && mScrollY > 0)
							|| (mScrollDy > 0 && mScrollY < 0)) {
						mScrollY = 0;
					}

					mChildRootView.scrollTo(0, mScrollY);
					sendEmptyMessageDelayed(MSG_REST_POSITION, 20);
				}

			}
		}

	};

	public StretchScrollView(Context context) {
		super(context);

		init();
	}

	public StretchScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);

		init();
	}

	public StretchScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		init();
	}

	private void init() {
		// set scroll mode
		setOverScrollMode(OVER_SCROLL_NEVER);
	}

	@Override
	protected void onFinishInflate() {
		// TODO Auto-generated method stub
		if (getChildCount() > 0)
			mChildRootView = getChildAt(0);
		super.onFinishInflate();
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		if (mChildRootView != null) {
			commOnTouchEvent(ev);
		}
		return super.onTouchEvent(ev);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			mTouchY = ev.getY();
		}
		return super.onInterceptTouchEvent(ev);
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	public void commOnTouchEvent(MotionEvent ev) {
		int action = ev.getAction();

		switch (action) {
		case MotionEvent.ACTION_UP:
			mScrollY = mChildRootView.getScrollY();
			if (mScrollY != 0) {
				mTouchStop = true;
				mScrollDy = (int) (mScrollY / 10.0f);
				mHandler.sendEmptyMessage(MSG_REST_POSITION);
			}
			break;

		case MotionEvent.ACTION_MOVE:
			float nowY = ev.getY();
			int deltaY = (int) (mTouchY - nowY);
			mTouchY = nowY;
			if (isNeedMove()) {
				int offset = mChildRootView.getScrollY();
				if (offset < MAX_SCROLL_HEIGHT && offset > -MAX_SCROLL_HEIGHT) {
					mChildRootView.scrollBy(0, (int) (deltaY * SCROLL_RATIO));
					mTouchStop = false;
				}
			}
			break;

		default:
			break;
		}
	}

	//

    private boolean isNeedMove() {
        int viewHeight = mChildRootView.getMeasuredHeight();
        int scrollHeight = getHeight();
        int offset = viewHeight - scrollHeight;
        int scrollY = getScrollY();

        return scrollY == 0 || scrollY == offset;
    }
}
